<?php
    /**
     * Created by PhpStorm.
     * User: huangzhongwei
     * Date: 2018/10/25
     * Time: 14:36
     */

    namespace app\api\service;

    use app\common\model\Goods;
    use app\common\model\HarvestAddress;
    use app\common\model\PickUpGoods;
    use app\common\model\Weight;
    use app\lib\exception\MissException;
    use app\common\model\AccountHasVoucher;
    use app\common\model\Order as OrderModel;
    use app\common\model\OrderGoods;
    use app\common\model\University;
    use app\lib\exception\OrderException;


    class Order
    {
        //订单类型
        protected $order_type;
        //用户id
        protected $uid;
        //订单提交商品
        protected $oGoods;
        //用户订单
        protected $order_id;
        //数据库商品
        protected $goods;
        //入库的订单信息
        protected $orderGoodsInfo;
        //优惠卷
        protected $voucher = 0;
        //小费
        protected $tip = 0;
        //收获地址
        protected $harvest_address_id;
        //取货重量价格
        protected $weight_price;


        public function __construct()
        {

        }

        //帮我买订单检查
        public function place($data)
        {
            $this->checkOrder($data);

            //提交订单
            return $this->createOrderByTrans($this->orderGoodsInfo, $data);


        }

        //帮我取订单检查
        public function recevierPlace($data)
        {
            $this->checkOrder($data);
            return $this->createReceiver($data);
        }


        public function checkOrder($data, $order_id = -1)
        {
            $this->uid      = $order_id == -1 ? $data['uid'] : $data['account_id'];
            $this->order_id = $order_id;


            // 帮我买检测商品
            if ($data['order_type'] == 1) {

                $this->goods = $this->getGoodsByOrder($this->order_id == -1 ? $data['goods'] : $data['order_goods']);

                $this->orderGoodsInfo = $this->getOrderState();
            }
            //帮我取 计算订单价格 计算路程

            if ($data['order_type'] == 2) {
                //检查取件类型
                $this->checkPickUpGoods($data['pick_up_goods_id']);
                //检查货品重量
                $this->checkWeight($data['weight_id']);
                //检查取货地址

                $this->checkReceiverAddress($data['pick_up_address_id']);

            }

            //检查订单状态 超时不能支付
            if ($order_id != -1) {
                if ($data['state'] == 6) {
                    throw new OrderException(['msg' => '订单支付已超时', 'errorCode' => 60008]);
                }
            }

            //检测大学是否存在
            $this->checkUniversity($data['university_id']);


            //检测优惠卷
            if (isset($data['account_has_voucher_id']) && !empty($data['account_has_voucher_id']))
                $this->checkVoucher($data['account_has_voucher_id']);

            //检测小费
            if (!empty($data['tip']))
                $this->tip = $data['tip'];//转换成分


            //检测收货地址

            $this->checkAddress($data['harvest_address_id']);
        }

        //检测取件类型
        public function checkPickUpGoods($id)
        {
            $pickupgoods = (new PickUpGoods())->get($id);
            if (!$pickupgoods) {
                throw new MissException(['msg' => '订单取件类型不存在，订单创建失败', 'errorCode' => 60003]);
            }
            return true;
        }

        //检测取件重量
        public function checkWeight($id)
        {
            $weight = (new Weight())->get($id);
            if (!$weight) {
                throw new MissException(['msg' => '订单重量不存在，订单创建失败', 'errorCode' => 60004]);
            }
            $this->weight_price = $weight->price;
            return true;
        }


        //检测大学
        public function checkUniversity($id)
        {
            $university = (new University())->get($id);
            if (!$university) {
                throw new MissException(['msg' => '订单大学不存在，订单创建失败', 'errorCode' => 60005]);
            }
            return true;
        }


        //检测优惠卷
        public function checkVoucher($voucher)
        {
            if (empty($voucher))
                return;
            $is_used           = $this->order_id != -1 ? 2 : 0;
            $AccountHasVoucher = AccountHasVoucher::where(['id' => $voucher, 'is_used' => $is_used])
                                                  ->with('voucher')->find();
            if (!$AccountHasVoucher) {
                throw new MissException(['msg' => '当前优惠卷已失效,订单创建失败', 'errorCode' => 60001]);
            }


            $this->voucher = ($AccountHasVoucher->voucher->money);//转换成分

            return true;
        }

        //检测收货地址
        public function checkAddress($id)
        {

            $address = HarvestAddress::where('type', 1)->get($id);
            if (!$address) {
                throw new MissException(['msg' => '当前订单收货地址不存在，订单创建失败', 'errorCode' => 60002]);
            }
            return true;
        }


        //检测取货地址
        public function checkReceiverAddress($id)
        {
            $address = HarvestAddress::where('type', 2)->get($id);
            if (!$address) {
                throw new MissException(['msg' => '当前订单取货地址不存在，订单创建失败', 'errorCode' => 60003]);
            }
            return true;
        }

        //根据订单商品 获取 真实商品
        public function getGoodsByOrder($oGoods)
        {
            $oGoodsId = [];

            $this->oGoods = $oGoods;

            foreach ($oGoods as $item) {
                array_push($oGoodsId, $item['goods_id']);
            }
            $goods = Goods::all($oGoodsId);
            return $goods;
        }

        //真实商品 与订单商品比对 计算总价与总额
        public function getOrderState()
        {
            $orderState = [
                'pass'            => true,
                'orderPrice'      => 0,
                'orderCount'      => 0,
                'goodsStateArray' => [],
            ];

            foreach ($this->oGoods as $item) {

                $goodState = $this->getGoodsState($item['goods_id'], $item['count'], $this->goods);

                $orderState['orderPrice'] += $goodState['totalPrice'];
                $orderState['orderCount'] += $goodState['count'];
                array_push($orderState['goodsStateArray'], $goodState);
            }

            return $orderState;
        }


        public function getGoodsState($oGid, $oCount, $goods)
        {
            $gIndex = -1;
            for ($i = 0; $i < count($goods); $i++) {
                if ($oGid == $goods[$i]['id']) {
                    $gIndex = $i;
                }
            }

            if ($gIndex == -1) {
                throw new MissException(['msg' => 'id为' . $oGid . '的商品不存在，订单创建失败', 'errorCode' => 60000]);
            } else {
                $good                  = $goods[$gIndex];
                $gStatus['id']         = $good['id'];
                $gStatus['name']       = $good['goods_name'];
                $gStatus['count']      = $oCount;
                $gStatus['totalPrice'] = $good['price'] * $oCount;
            }
            return $gStatus;
        }


        /**帮我买 下单
         *
         * @param $snap
         * @param $data
         *
         * @return array
         * @throws \Exception
         */
        private function createOrderByTrans($snap, $data)
        {
            try {
                $orderNo                    = $this->makeOrderNo();
                $order                      = new OrderModel();
                $order_price                = $snap['orderPrice'] + $this->tip + $data['door_money'] - $this->voucher;
                //跑男接单价

                $orderAccountPrice          = ($snap['orderCount'] + $this->tip+$data['door_money'])*0.6+($snap['orderPrice']-$snap['orderCount']);
                $order->account_id          = $this->uid;
                $order->order_no            = $orderNo;
                $order->order_price         = $order_price <= 0 ? 0.01 : $order_price;

                $order->order_account_price = $orderAccountPrice<= 0 ? 0.01:$orderAccountPrice;
                $order->goods_count         = $snap['orderCount'];
                $order->order_type          = $data['order_type'];

                $order->harvest_address_id = $data['harvest_address_id'];
                $order->delivery_to_home   = $data['delivery_to_home'];
                $order->instruction_manual = $data['instruction_manual'];
                $order->buy_time           = $data['buy_time'];
                $order->tip                = $this->tip;
                $order->door_money         = $data['door_money'];
                if (isset($data['account_has_voucher_id']) && !empty($data['account_has_voucher_id']))
                    $order->account_has_voucher_id = $data['account_has_voucher_id'];
                $order->expire_time   = time() + 15 * 60;
                $order->university_id = $data['university_id'];

                $order->save();

                //改变优惠卷状态 0->2 下单 待支付->优惠卷占用 支付后改为已使用
                if (isset($data['account_has_voucher_id']) && !empty($data['account_has_voucher_id']))
                    $this->changeVoucher($data['account_has_voucher_id']);


                $orderID     = $order->id;
                $create_time = $order->create_time;
                foreach ($this->oGoods as &$p) {
                    $p['order_id'] = $orderID;
                }
                $orderProduct = new OrderGoods();
                $orderProduct->saveAll($this->oGoods);
                return $orderID;
            } catch (Exception $ex) {
                throw $ex;
            }
        }

        /**
         * 帮我取下单
         *
         * @param $data
         *
         * @return array
         */
        private function createReceiver($data)
        {
            try {
                $orderNo                    = $this->makeOrderNo();
                $order                      = new OrderModel();
                $order_price                = $this->weight_price + $this->tip + $data['door_money'] - $this->voucher;
                //跑男接单价
                $orderAccountPrice          = ($this->weight_price + $this->tip+ $data['door_money'])*0.6;
                $order->account_id          = $this->uid;
                $order->order_no            = $orderNo;
                $order->order_price         = $order_price <= 0 ? 0.01 : $order_price;
                $order->order_account_price = $orderAccountPrice<= 0 ? 0.01:$orderAccountPrice;
                $order->order_type          = $data['order_type'];
                $order->harvest_address_id  = $data['harvest_address_id'];
                $order->delivery_to_home    = $data['delivery_to_home'];
                $order->instruction_manual  = $data['instruction_manual'];
                $order->buy_time            = $data['buy_time'];
                $order->tip                 = $this->tip;
                $order->door_money          = $data['door_money'];
                if (isset($data['account_has_voucher_id']) && !empty($data['account_has_voucher_id']))
                    $order->account_has_voucher_id = $data['account_has_voucher_id'];//优惠卷id

                $order->pick_up_goods_id   = $data['pick_up_goods_id'];
                $order->weight_id          = $data['weight_id'];
                $order->sms_screenshot     = $data['sms_screenshot'];
                $order->pick_up_address_id = $data['pick_up_address_id'];
                $order->university_id      = $data['university_id'];
                $order->expire_time        = time() + 15 * 60;
                $order->save();
                $orderID     = $order->id;
                $create_time = $order->create_time;

                //改变优惠卷状态 0->2 下单 待支付->优惠卷占用 支付后改为已使用
                if (isset($data['account_has_voucher_id']) && !empty($data['account_has_voucher_id']))
                    $this->changeVoucher($data['account_has_voucher_id']);

                return $orderID;
            } catch (Exception $ex) {
                throw $ex;
            }
        }


        public function changeVoucher($id)
        {
            //改变优惠卷状态 0->2 下单 待支付->优惠卷占用 支付后改为已使用

            $accountVoucher = (new AccountHasVoucher())->get($id);
            if ($accountVoucher) {
                $accountVoucher->is_used = 2;
                $accountVoucher->save();
            }

            return true;
        }


        /**
         * 订单号
         * @return string
         */
        public static function makeOrderNo()
        {
            $yCode   = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'];
            $orderSn =
                $yCode[intval(date('Y')) - 2017] . strtoupper(dechex(date('m'))) . date(
                    'd') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf(
                    '%02d', rand(0, 99));
            return $orderSn;
        }


    }